﻿using System;
using System.IO;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Windows.Forms;
using System.Collections.Generic;

namespace Yb
{
    /// <summary>
    /// JSON 配置管理器，支持点分路径读写，线程安全，文件不存在自动创建
    /// 所有方法异常安全，永不抛出异常，无任何外部依赖（如 Base.Log）
    /// </summary>
    public class Config
    {
        private readonly string _filePath;
        private JObject _root;
        private readonly object _lock = new object();
        private static readonly char[] KeySeparator = { '.' };

        // 调试开关：发布时设为 false
        private static readonly bool _enableDebugOutput = false;

        /// <summary>
        /// 构造函数：自动加载配置文件（失败则初始化空配置，不抛异常）
        /// </summary>
        public Config(string fileName = "config.json")
        {
            if (string.IsNullOrWhiteSpace(fileName))
                fileName = "config.json";

            _filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName);

            try
            {
                Reload();
            }
            catch (Exception ex)
            {
                DebugWriteLine($"Config 构造函数初始化失败: {ex.Message}");
                _root = new JObject(); // 降级处理
            }
        }

        /// <summary>
        /// 从文件重新加载配置（线程安全，异常安全）
        /// </summary>
        public void Reload()
        {
            lock (_lock)
            {
                LoadFromFile();
            }
        }

        /// <summary>
        /// 读取配置中的列表值，异常安全
        /// </summary>
        public List<T> GetList<T>(string key, List<T> defaultValue = null)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(key))
                {
                    DebugWriteLine("GetList: key 为空");
                    return defaultValue ?? new List<T>();
                }

                lock (_lock)
                {
                    if (_root == null)
                        _root = new JObject();

                    var segments = key.Split(KeySeparator, StringSplitOptions.RemoveEmptyEntries);
                    if (segments.Length == 0)
                        return defaultValue ?? new List<T>();

                    JToken current = _root;
                    foreach (var segment in segments)
                    {
                        if (current[segment] == null || current[segment].Type == JTokenType.Null)
                            return defaultValue ?? new List<T>();

                        current = current[segment];
                    }

                    if (current.Type == JTokenType.Array)
                    {
                        var list = new List<T>();
                        foreach (JToken item in (JArray)current)
                        {
                            try
                            {
                                list.Add(item.ToObject<T>());
                            }
                            catch (Exception ex)
                            {
                                DebugWriteLine($"列表元素转换失败 Key={key} Element={item} Type={typeof(T)} Error={ex.Message}");
                                // 跳过错误元素
                            }
                        }
                        return list;
                    }
                    else
                    {
                        DebugWriteLine($"配置项不是数组类型 Key={key} Type={current.Type}");
                        return defaultValue ?? new List<T>();
                    }
                }
            }
            catch (Exception ex)
            {
                DebugWriteLine($"GetList 失败 Key={key} Error={ex.Message}");
                return defaultValue ?? new List<T>();
            }
        }

        /// <summary>
        /// 设置列表值到配置并立即保存（异常安全）
        /// </summary>
        public void SetList<T>(string key, List<T> value)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(key))
                {
                    DebugWriteLine("SetList: key 为空");
                    return;
                }

                if (value == null)
                {
                    DebugWriteLine("SetList: value 为 null");
                    return;
                }

                Set(key, value);
            }
            catch (Exception ex)
            {
                DebugWriteLine($"SetList 失败 Key={key} Error={ex.Message}");
            }
        }

        /// <summary>
        /// 读取配置值，支持泛型，异常安全
        /// </summary>
        public T Get<T>(string key, T defaultValue = default(T))
        {
            try
            {
                if (string.IsNullOrWhiteSpace(key))
                {
                    DebugWriteLine("Get: key 为空");
                    return defaultValue;
                }

                lock (_lock)
                {
                    if (_root == null)
                        _root = new JObject();

                    var segments = key.Split(KeySeparator, StringSplitOptions.RemoveEmptyEntries);
                    if (segments.Length == 0)
                        return defaultValue;

                    JToken current = _root;
                    foreach (var segment in segments)
                    {
                        if (current[segment] == null || current[segment].Type == JTokenType.Null)
                            return defaultValue;

                        current = current[segment];
                    }

                    JTokenType type = current.Type;
                    Type targetType = typeof(T);

                    if (type == JTokenType.Integer && targetType == typeof(int))
                        return (T)(object)current.Value<int>();
                    if (type == JTokenType.Float && targetType == typeof(double))
                        return (T)(object)current.Value<double>();
                    if (type == JTokenType.String && targetType == typeof(string))
                        return (T)(object)current.Value<string>();
                    if (type == JTokenType.Boolean && targetType == typeof(bool))
                        return (T)(object)current.Value<bool>();
                    if (type == JTokenType.Integer && targetType == typeof(long))
                        return (T)(object)current.Value<long>();
                    if (type == JTokenType.Float && targetType == typeof(float))
                        return (T)(object)current.Value<float>();

                    return current.ToObject<T>();
                }
            }
            catch (Exception ex)
            {
                DebugWriteLine($"Get 失败 Key={key} Type={typeof(T)} Error={ex.Message}");
                return defaultValue;
            }
        }

        /// <summary>
        /// 设置配置值并立即保存到文件（异常安全）
        /// </summary>
        public void Set<T>(string key, T value)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(key))
                {
                    DebugWriteLine("Set: key 为空");
                    return;
                }

                lock (_lock)
                {
                    if (_root == null)
                        _root = new JObject();

                    var segments = key.Split(KeySeparator, StringSplitOptions.RemoveEmptyEntries);
                    if (segments.Length == 0)
                    {
                        DebugWriteLine($"Set: 无效路径格式 Key={key}");
                        return;
                    }

                    JToken current = _root;
                    for (int i = 0; i < segments.Length; i++)
                    {
                        var segment = segments[i];
                        if (i == segments.Length - 1)
                        {
                            if (current is JObject obj)
                            {
                                obj[segment] = JToken.FromObject(value);
                            }
                            break;
                        }

                        if (!(current is JObject parent))
                        {
                            DebugWriteLine($"Set: 路径冲突，非对象节点 Key={key} Segment={segment}");
                            break;
                        }

                        if (parent[segment] == null || parent[segment].Type != JTokenType.Object)
                        {
                            parent[segment] = new JObject();
                        }

                        current = parent[segment];
                    }

                    SaveToFileUnsafe();
                }
            }
            catch (Exception ex)
            {
                DebugWriteLine($"Set 失败 Key={key} Error={ex.Message}");
            }
        }

        /// <summary>
        /// （内部）保存到文件，不加锁（由外层方法保证线程安全）
        /// </summary>
        private void SaveToFileUnsafe()
        {
            try
            {
                string dir = Path.GetDirectoryName(_filePath);
                if (!string.IsNullOrEmpty(dir) && !Directory.Exists(dir))
                {
                    Directory.CreateDirectory(dir);
                }

                string json = _root.ToString(Formatting.Indented);
                File.WriteAllText(_filePath, json, Encoding.UTF8);
            }
            catch (Exception ex)
            {
                DebugWriteLine($"保存文件失败: {_filePath} | {ex.Message}");
            }
        }

        private void LoadFromFile()
        {
            try
            {
                if (!File.Exists(_filePath))
                {
                    _root = new JObject();
                    return;
                }

                string content = File.ReadAllText(_filePath, Encoding.UTF8);
                _root = JObject.Parse(content);
            }
            catch (JsonReaderException ex)
            {
                DebugWriteLine($"JSON格式错误，使用空配置: {ex.Message}");
                _root = new JObject();
            }
            catch (Exception ex)
            {
                DebugWriteLine($"加载配置失败: {ex.Message}");
                _root = new JObject();
            }
        }

        private void DebugWriteLine(string message)
        {
            if (_enableDebugOutput)
            {
                try
                {
                    System.Diagnostics.Debug.WriteLine($"[Yb.Config] {message}");
                }
                catch
                {
                    // 防御性：写调试输出失败也不应导致异常
                }
            }
        }
    }
}